Skip to content

[Attention] Enable FA4 sparse MQA decode on Blackwell - #55866

Merged
MatthewBonanni merged 16 commits into
vllm-project:mainfrom
simon-veitner-redhat:sparse-mqa
Oct 13, 2026
Merged

MatthewBonanni merged 16 commits into
vllm-project:mainfrom
simon-veitner-redhat:sparse-mqa

Conversation

@simon-veitner-redhat

@simon-veitner-redhat simon-veitner-redhat commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

[Attention] Enable FA4 sparse MQA decode on Blackwell

This adds FLASH_ATTN_MLA_SPARSE_FA4, a sparse MLA backend for Blackwell with a BF16 KV cache. The FA4 CuTe DSL kernel from vllm-project/flash-attention#195 serves decode batches and the decode rows of mixed HiSparse batches. Every other batch runs on the trtllm-gen lane, as in FLASHINFER_MLA_SPARSE. At 16 or fewer query heads per rank the backend is the first choice, with and without HiSparse; above that head count it stays opt-in.

The first commit, "Share sparse MLA MQA cache handling", will go up as its own PR and is only here until it lands. It moves index conversion and the HiSparse lane split from the FA3 and FlashInfer sparse MLA backends into SparseMLACommonImpl.forward_mqa, so a backend implements only _forward_mqa_kernel(..., is_decode). The design is by @LucasWilkinson. One FA3 behaviour changes with it: FA3's plain path converts top-k through the index group's shared buffer, as FlashInfer already did, instead of once per layer. The values are identical while the layers of a group share block stride, block table and request ids, which index groups guarantee. A test pins leader and follower layers.

The second commit is the FA4 backend on top of that hook:

  • flash_attn_varlen_func forwards gather_kv_indices, gather_kv_valid_length and q_v to FA4.
  • The impl subclasses FlashInferMLASparseImpl. Its hook runs the FA4 decode kernel when is_decode, otherwise FlashInfer's trtllm-gen call with the LSE converted to base e.
  • The metadata builder subclasses the FlashInfer TRTLLM builder and declares UNIFORM_BATCH CUDA graph support. Inheriting the builder brings the DCP workspace pre-size: an earlier version of this PR used the default 394 MiB trtllm workspace on its prefill lane and crashed under DCP 2 on a prefill step of about 8192 tokens, where the softmax-stats slab needs 513 MiB.
  • The backend class subclasses the FlashInfer TRTLLM backend for its gates (PCP with DCP rejected, head dims) and adds the FA4 gates: index_topk a multiple of 128, and a supported gathered head count under DCP.
  • Under HiSparse, decode reads the hot buffer through the shared lanes. The inherited autotune_hisparse_decode compiles the FA4 kernel before graph capture.
  • FA4 shares FlashInfer's masked-MHA thresholds.
  • FA4 joins _uses_flat_kv_cache, since it reads the same flat KV cache as FlashInfer.

The last commit bumps the flash-attention pin to vllm-project/flash-attention 2e3a6694, which has #195 and the sparse decode split-rule tuning for DCP shapes (vllm-project/flash-attention#200).

Performance

GLM-5.2 NVFP4-FP8 with BF16 KV on B300, TP4, FA4 against FLASHINFER_MLA_SPARSE from the same tree (this PR on main d71f662), change in median ITL (negative favours FA4). Plain and DCP 2 are averaged over two runs. The HiSparse column assumes #59309 is merged: it applies that PR's diff, pins the MoE autotune tactics so both backends run the same MoE kernels, and averages two server starts with two runs each.

Input / concurrency / output TP4 plain TP4 DCP 2 TP4 HiSparse
4096 / 8 / 256 -4.2% -6.7% -0.8%
4096 / 128 / 256 -4.3% -2.3% +1.3%*
32768 / 16 / 256 -5.3% -5.1% +0.2%

* One FA4 run measured 35.2 ms against 33.4 to 33.7 ms for the other three; without it the figure is +0.1%.

Under HiSparse FA4 is on par with FlashInfer, which did not justify a separate priority order. Per decode step, FA4's attention kernels take about 190 µs less than FlashInfer's at 4096 / 8, but start-to-start variance in all-reduce time is larger than that difference. On current main, #59235 makes HiSparse about 0.45 ms per decode step slower for both backends, because it writes request_ids in every layer. #59309 moves those writes into the group leader's resolve, which brings the 57 follower layers' 171 kernels per step back out of the decode graph.

Validation

  • pytest tests/v1/attention/test_sparse_mla_backends.py: 475 passed, 672 skipped. pytest tests/v1/e2e/general/test_hisparse.py: 5 passed (FlashInfer and FA4). The FlashInfer, KV cache layout, backend selection and masked-MHA routing tests pass as well.
  • Serving, GLM-5.2 NVFP4-FP8, TP4, HiSparse, GSM8K (500 questions, 5-shot): FA4 0.936, FA4 with MTP 0.948, FlashInfer 0.946. No invalid responses; 8K, 16K and 30K needle prompts answered correctly.
  • FlashInfer on the shared base: latency within noise of main, plain generations byte-identical.
  • The FA3 sparse backend did not run on hardware here (SM90 kernel, SM100 machine); its change is covered by unit tests only.

AI-assisted. The September 7 upstream search found no matching open FA4 sparse-MLA integration PR; related platform-specific work does not provide this SM100 backend.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@mergify

mergify Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @simon-veitner-redhat.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify

mergify Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @simon-veitner-redhat.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@github-actions

Copy link
Copy Markdown

❌ This PR is 57 commits behind upstream main. Your branch must contain every commit currently on upstream main. No new CI build was started. Merge or rebase onto the latest main, then rerun /ci run. To test this branch at your own risk, use /ci run --allow-stale.

@MatthewBonanni

Copy link
Copy Markdown
Member

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #94216 for commit 4d3b1d8ff9a6.

@vllm-agent

vllm-agent commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

CI selector (shadow): 194 test steps (270 jobs) instead of 195 (271 jobs)

Shadow mode: this changes nothing about what CI runs. It shows what the evidence-based selector would pick for this PR, next to today's rules. How it works.

Feedback welcome: reply here if it would skip a step this change needs, or runs something unrelated.

steps (jobs) Today's rules Selector Would skip Would add
NVIDIA, CPU and others 195 (271) 194 (270) 1 (1) 0 (0)
AMD mirrors 163 (227) 160 (224) 3 (3) 0 (0)

Today's rules run everything for this diff.

Selector would run (194)
  • amd-fp8-moe-kernels-mi355
  • amd-kernels-mi355
  • amd-lm-eval-small-models-harness
  • amd-native-quantization-kernels-mi355
  • amd-qwen3-next-mtp-async-eplb-accuracy
  • arm-cpu-test ×3
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • basic-models-test-other-cpu
  • basic-models-tests-extra-initialization ×14
  • basic-models-tests-initialization
  • basic-models-tests-other
  • batch-invariance-b200
  • batch-invariance-h100
  • benchmarks-cli-test
  • cpu-distributed-tests-dp-tp
  • cpu-distributed-tests-pp-tp
  • cpu-kernel-tests ×2
  • cpu-language-generation-and-pooling-model-tests ×3
  • cpu-multi-modal-model-tests-n ×4
  • cpu-multimodal-config
  • cpu-params-env-tokenizers-parser
  • cpu-quantization-model-tests
  • cpu-qwen2-5-vl-multimodal-tests
  • cpu-reasoning-renderers
  • cpu-spec-decode-tests
  • cpu-tool-parsers
  • crcr-report
  • crosslayer-kv-layout-distributed-nixlconnector-pd-accuracy-tests-4-gpus
  • cudagraph
  • deepseek-v4-kernel-test-b200
  • deepseek-v4-kernel-test-h100
  • distributed-comm-ops
  • distributed-compile-comm-4-gpus
  • distributed-compile-rpc-tests-2-gpus
  • distributed-compile-unit-tests-2xh100
  • distributed-dp-tests-2-gpus
  • distributed-dp-tests-4-gpus
  • distributed-flashinfer-nixlconnector-pd-accuracy-4-gpus
  • distributed-model-tests-2-gpus ×3
  • distributed-mooncakeconnector-pd-accuracy-4-gpus
  • distributed-nixlconnector-pd-accuracy-4-gpus
  • distributed-torchrun-examples-4-gpus
  • distributed-torchrun-shutdown-tests-2-gpus
  • docker-build-metadata
  • dp-ep-distributed-nixlconnector-pd-accuracy-tests-4-gpus
  • dsv41-mono-decode-numerics-amd
  • e2e-core-1-gpu
  • e2e-core-large-memory
  • e2e-scheduling-1-gpu
  • e2e-scheduling-accuracy-1-gpu
  • elastic-ep-scaling-test
  • engine
  • engine-1-gpu
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-chat_completion
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-llm
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-responses-api
  • entrypoints-integration-speech_to_text
  • entrypoints-unit-tests
  • eplb-algorithm
  • eplb-execution
  • examples
  • extract-hidden-states-integration
  • extract-hidden-states-integration-2-gpus
  • fault-tolerance-e2e-2xh100
  • fusion-and-compile-unit-tests-2xb200
  • fusion-e2e-config-sweep-h100
  • fusion-e2e-quick-h100
  • fusion-e2e-tp2-ar-rms-config-sweep-h100
  • fusion-e2e-tp2-ar-rms-dynamo-partition-amd
  • fusion-e2e-tp2-ar-rms-inductor-partition-amd
  • fusion-e2e-tp2-b200
  • fusion-e2e-tp2-quick-h100
  • gemm-rs-ar-2xb200
  • glm5next-unit-tests
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus
  • hybrid-ssm-nixlconnector-pd-prefix-cache-2-gpus
  • inkling-unit-tests-b200
  • intel-hpu-test
  • jit-monitor-no-runtime-jit
  • kernels-attention-diffkv-test-h100
  • kernels-attention-test ×7
  • kernels-b200 ×3
  • kernels-core-operation-test ×3
  • kernels-deepgemm-test-h100
  • kernels-fla-ops-test-b200
  • kernels-flashmla-test-h100
  • kernels-fusedmoe-layer-test-2-b200s
  • kernels-fusedmoe-layer-test-2-h100s
  • kernels-helion-test ×5
  • kernels-mamba-test
  • kernels-mhc-test-b200
  • kernels-minimax-m3-attention-b200
  • kernels-minimax-reduce-rms-test-2-gpus
  • kernels-moe-test ×5
  • kernels-quantization-test ×6
  • kernels-root-misc-test-b200
  • kimi-k3-prefix-cache-4xb200 ×2
  • kimi-k3-unit-tests-b200
  • kv-offload-large
  • kv-offload-medium
  • kv-offload-small
  • language-models-tests-extra-standard ×2
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • lm-eval-dspark-watermark-2xh100
  • lm-eval-small-models
  • lm-eval-turboquant-k3v4nc
  • lm-eval-turboquant-k8v4
  • lm-eval-turboquant-t3nc
  • lm-eval-turboquant-t4nc
  • lm-eval-watermarking
  • lora ×4
  • lora-tp-distributed ×4
  • metrics-tracing-2-gpus
  • model-executor
  • mooncake-ec-tcp-e2e-2-gpus
  • mrcr-eval-small-models
  • multi-modal-accuracy-eval-small-models
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-models-standard-4-other-whisper
  • multi-modal-processor ×4
  • multi-modal-processor-cpu ×4
  • multiconnector-nixl-offloading-pd-accuracy-2-gpus
  • multiconnector-nixl-offloading-pd-edge-cases-2-gpus
  • nixlconnector-pd-edge-cases-2-gpus
  • openai-api-correctness
  • pipeline-context-parallelism-4-gpus
  • platform-tests
  • plugin-tests-2-gpus
  • push-nixlconnector-pp-prefill-pd-accuracy-4-gpus
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-passes-unit-tests
  • pytorch-compilation-unit-tests
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • pytorch-fullgraph-test
  • pytorch-nightly-dependency-override-check
  • quantization ×4
  • quantized-fusions
  • quantized-models-test
  • quantized-moe-test-b200
  • qwen4-exp-sp-tests-4-gpus
  • qwen4-exp-unit-tests
  • qwen4-exp-unit-tests-cpu
  • ray-dependency-compatibility-check
  • rayexecutorv2-4-gpus
  • regression
  • replayssm-e2e
  • rl-entrypoints-tests
  • rust-frontend-cargo-style-clippy
  • rust-frontend-cargo-tests
  • rust-frontend-core-correctness
  • rust-frontend-distributed
  • rust-frontend-openai-coverage
  • rust-frontend-serve-admin-coverage
  • rust-frontend-tool-use
  • samplers-multimodal-beam-search
  • samplers-test
  • scale-out-ec-e2e-2-gpus
  • sharded-rdt-weight-transfer
  • spec-decode-draft-model ×4
  • spec-decode-eagle-1-deepseek-qwen
  • spec-decode-eagle-2-llama3-qwen-vl-other
  • spec-decode-mtp-deepseek-mimo
  • spec-decode-mtp-gemma4
  • spec-decode-mtp-qwen3-5
  • spec-decode-ngram-suffix
  • spec-decode-speculators
  • torch-stable-abi-audit
  • v1-attention-b200 ×2
  • v1-attention-h100-mi300 ×2
  • v1-core
  • v1-executor-worker
  • v1-kv-connectors ×4
  • v1-kv-offload
  • v1-logits-oracle
  • v1-metrics-lmeval
  • v1-others-cpu
  • v1-sample
  • v1-spec-decode
  • vllm-ir-tests
Would skip (today's rules run them) (1)
  • ascend-npu-test
Would add (today's rules do not run them) (0)

none

AMD mirrors: would skip (3)
  • pytorch-nightly-dependency-override-check
  • ray-dependency-compatibility-check
  • torch-stable-abi-audit
AMD mirrors: would add (0)

none

14 changed files · base abad32a718 · head 4131823817 · Python record: build 93039 at 1e5d0ea888 · kernel record: table fe341a5 (build 94315), map fe341a5 · not counted: 11 build steps, 5 A100 steps the generator no longer emits, 138 optional steps the selector would also run

@mergify

mergify Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @simon-veitner-redhat.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Oct 12, 2026
@simon-veitner-redhat

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ CI is already running for this commit: https://buildkite.com/vllm/ci/builds/94216

simon-veitner-redhat and others added 2 commits October 12, 2026 19:55
Signed-off-by: Simon Veitner <sveitner@redhat.com>
Restore main's `flashattn_sparse_module` alias for
vllm.v1.attention.backends.mla.flashattn_mla_sparse, imported under the
`if current_platform.is_cuda():` guard, which was dropped during the merge
resolution. Use it in `_record_fa4_kernels` and `test_fa4_sparse_gate`
instead of their per-test imports. No behaviour change.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Veitner <sveitner@redhat.com>
@mergify mergify Bot removed the needs-rebase label Oct 13, 2026
@simon-veitner-redhat

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

❌ This PR is 30 commits behind upstream main. Your branch must contain every commit currently on upstream main. No new CI build was started. Merge or rebase onto the latest main, then rerun /ci run. To test this branch at your own risk, use /ci run --allow-stale.

Signed-off-by: Simon Veitner <sveitner@redhat.com>
@simon-veitner-redhat

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

❌ This PR is 1 commit behind upstream main. Your branch must contain every commit currently on upstream main. No new CI build was started. Merge or rebase onto the latest main, then rerun /ci run. To test this branch at your own risk, use /ci run --allow-stale.

Signed-off-by: Simon Veitner <sveitner@redhat.com>
@simon-veitner-redhat

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #94434 for commit 1944857356d8.

@MatthewBonanni MatthewBonanni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@MatthewBonanni
MatthewBonanni merged commit 31e90ac into vllm-project:main Oct 13, 2026
490 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to Done in NVIDIA Oct 13, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in AMD Oct 13, 2026
MatthewBonanni added a commit to MatthewBonanni/vllm that referenced this pull request Oct 13, 2026
…taging

Resolve against vllm-project#55866, which moved the HiSparse lane split into
SparseMLACommonImpl.forward_mqa: the shared lane now stages prefills per
group via staged_prefills and writes every lane into one output through
an out= argument on _forward_mqa_kernel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
AndreasKaratzas pushed a commit to AndreasKaratzas/vllm that referenced this pull request Oct 16, 2026
…5866)

Signed-off-by: Simon Veitner <sveitner@redhat.com>
Co-authored-by: Lucas Wilkinson <lwilkins@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Lucas Wilkinson <LucasWilkinson@users.noreply.github.com>
Co-authored-by: Matthew Bonanni <mbonanni@redhat.com>

Signed-off-by: Andreas Karatzas <AndreasKaratzas@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/build documentation Improvements or additions to documentation nvidia ready ONLY add when PR is ready to merge/full CI is needed rocm Related to AMD ROCm

Projects

Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants